﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace IEx.Utilities
{
    public class RegexUtility
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="emailAddress"></param>
        /// <returns></returns>
        public static bool ValidateEmail(string emailAddress)
        {
            return !string.IsNullOrEmpty(emailAddress)
                && System.Text.RegularExpressions.Regex.IsMatch(emailAddress,
                        @"\b[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b",
                        System.Text.RegularExpressions.RegexOptions.Compiled
                        | System.Text.RegularExpressions.RegexOptions.Singleline);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string ExtractViewState(string s)
        {
            string viewStateNameDelimiter = "__VIEWSTATE";
            string valueDelimiter = "value=\"";

            int viewStateNamePosition = s.IndexOf(viewStateNameDelimiter);
            if (viewStateNamePosition == -1)
                return string.Empty;

            int viewStateValuePosition = s.IndexOf(
                  valueDelimiter, viewStateNamePosition
               );
            int viewStateStartPosition = viewStateValuePosition +
                                         valueDelimiter.Length;
            int viewStateEndPosition = s.IndexOf("\"", viewStateStartPosition);
            return s.Substring(
                        viewStateStartPosition,
                        viewStateEndPosition - viewStateStartPosition
                  );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="tagName"></param>
        /// <returns></returns>
        public static Regex CreateRegexByHtmlTag(string tagName)
        {
            return new Regex(String.Format(@"(?<{0}><{0}[^>]*>\s*([\S\s]*?)\s*</{0}>)", tagName),
                                RegexOptions.IgnoreCase | RegexOptions.Multiline);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        public static string ExtractTextFromHtmlTag(string html)
        {
            Regex regex = new Regex(@"(<.*?>)+", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            return regex.Replace(html, "");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="tagName"></param>
        /// <param name="html"></param>
        /// <returns></returns>
        public static string ExtractHtmlContent(string tagName, string html)
        {
            Regex pattern = new Regex(string.Concat(".*<", tagName, "[^>]*>(.*)</", tagName, ">.*"), RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase);
            return pattern.Replace(html, "$1");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sourceText"></param>
        /// <param name="matchString"></param>
        /// <param name="groupName"></param>
        /// <returns></returns>
        public static string ExtractHtmlContentByPattern(string sourceText, string matchString, string groupName = "")
        {
            string resultString = string.Empty;
            Regex regex = new Regex(matchString, RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Multiline);
            Match match = regex.Match(sourceText);
            if (!string.IsNullOrEmpty(groupName))
            {
                resultString = match.Groups[groupName].Value;
                return resultString;
            }
            else
            {
                while (match.Success)
                {
                    for (int i = 0; i < match.Groups.Count; i++)
                    {
                        Group GroupObj = match.Groups[i];
                        if (GroupObj.Success)
                        {
                            resultString = match.Value;
                        }
                    }
                    match = match.NextMatch();
                }
            }
            return resultString;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sourceText"></param>
        /// <returns></returns>
        public static string ExtractHyperlink(string sourceText)
        {
            string resultString = string.Empty;
            string matchString = "(?<=href=\")(?<link>.*?)(?=\")";
            Regex regex = new Regex(matchString, RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Multiline);
            MatchCollection matchs = regex.Matches(sourceText);
            Match match = null;
            if (matchs.Count > 0)
            {
                match = matchs[matchs.Count - 1];
            }

            if (match != null && match.Success && match.Groups["link"] != null)
            {
                resultString = match.Groups["link"].Value;
            }
            return resultString;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="html"></param>
        /// <param name="group"></param>
        /// <returns></returns>
        public static string ExtractHyperlink(string html, ref string textResult)
        {
            Regex regex = new Regex(@"<a.*?href=""(?<href>.+?)"".*?>(?<innerText>.*)</a>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            MatchCollection matches = regex.Matches(html);
            string href = "", innerText = "";
            if (matches != null)
            {
                foreach (Match match in matches)
                {
                    // Ignore inline javascript (e.g. href="javascript:functionA()")
                    if (match.Groups["href"].Value.IndexOfAny("()".ToCharArray()) == -1)
                    {
                        try
                        {
                            href = match.Groups["href"].Value;
                            innerText = match.Groups["innerText"].Value;
                        }
                        catch { }
                    }
                }
            }
            textResult = innerText;
            return href;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="nameAttribute"></param>
        /// <param name="html"></param>
        /// <returns></returns>
        public static string ExtractInputElementValue(string nameAttribute, string html)
        {
            Regex nameValueRegex = new Regex(string.Concat("<input\\s[^>]*name=\"[\\w\\d$]*", nameAttribute, "\".*value=\"(.*)\"[^>]*>"), RegexOptions.Compiled | RegexOptions.IgnoreCase);

            Match m = nameValueRegex.Match(html);
            if (m.Success)
                return m.Groups[1].Value;
            return string.Empty;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="nameAttribute"></param>
        /// <returns></returns>
        public static Regex CreateRegexWithInputName(string nameAttribute)
        {
            return new Regex(string.Concat("<input\\s[^>]*name=\"([\\w\\d$]*", nameAttribute, ")\"[^>]*>"), RegexOptions.Compiled | RegexOptions.IgnoreCase);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="originalLink"></param>
        /// <param name="article"></param>
        /// <returns></returns>
        public static List<string> ExtractMultipleLinkDownload(string originalLink, ref string article)
        {
            List<string> linkDownloadPdfs = new List<string>();

            HttpStatusCode status = HttpStatusCode.Accepted;
            string html = Utility.LoadHtml(originalLink, ref status);
            Uri baseUri = new Uri(originalLink);
            Regex regex = new Regex(@"<a.*?href=""(?<href>.+?)"".*?>(?<innerText>.*)</a>", RegexOptions.Compiled | RegexOptions.IgnoreCase);

            MatchCollection matches = regex.Matches(html);
            string href = "", innerText = "";
            if (matches != null)
            {
                foreach (Match match in matches)
                {
                    // Ignore inline javascript (e.g. href="javascript:functionA()")
                    if (match.Groups["href"].Value.IndexOfAny("()".ToCharArray()) == -1)
                    {
                        try
                        {
                            // Exception can be threw here
                            href = new Uri(baseUri, match.Groups["href"].Value).ToString();
                            //innerText = match.Groups["innerText"].Value;

                            // Remove any html tag
                            // if (!string.IsNullOrEmpty(innerText))
                            //innerText = ExtractTextFromHtmlTag(innerText);
                            linkDownloadPdfs.Add(new Uri(baseUri, match.Groups["href"].Value).ToString());
                        }
                        catch { }
                    }

                }
            }
            article = linkDownloadPdfs.Count != 0 ? string.Empty : html;

            return linkDownloadPdfs;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="imgTag"></param>
        /// <returns></returns>
        public static string ExtractSrcFromImgTag(string imgTag)
        {
            return Regex.Match(imgTag, "<img.+?src=[\"'](.+?)[\"'].*?>", RegexOptions.IgnoreCase).Groups[1].Value;
        }
    }
}
